﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.IO;
using System.Drawing;

namespace BasePlatformNet
{


    public delegate void Callback(bool succ, Object obj);
	public class Tools
	{
		#region 转换数据表

		static UInt32[] crcTable = {
 					0x0, 0x77073096, 0xee0e612c, 0x990951ba, 0x76dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
 					0xedb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x9b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
 					0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
 					0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
 					0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
 					0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
 					0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
 					0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
 					0x76dc4190, 0x1db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x6b6b51f, 0x9fbfe4a5, 0xe8b8d433,
 					0x7807c9a2, 0xf00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x86d3d2d, 0x91646c97, 0xe6635c01,
 					0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
 					0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
 					0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
 					0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
 					0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
 					0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
 					0xedb88320, 0x9abfb3b6, 0x3b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x4db2615, 0x73dc1683,
 					0xe3630b12, 0x94643b84, 0xd6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0xa00ae27, 0x7d079eb1,
 					0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
 					0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
 					0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
 					0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
 					0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
 					0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
 					0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x26d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x5005713,
 					0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0xcb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0xbdbdf21,
 					0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
 					0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
 					0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
 					0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
 					0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
 					0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
			};

		private static byte[] bitSwapTable = 
			{
					0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
					0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
					0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
					0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
					0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
					0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
					0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
					0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
					0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
					0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
					0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
					0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
					0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
					0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
					0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
					0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
					0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
					0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
					0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
					0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
					0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
					0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
					0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
					0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
					0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
					0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
					0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
					0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
					0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
					0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
					0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
					0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
			};

        #endregion

		// byte[] 转 string
		public static string Byte2HexString(byte[] bytes)
		{
			StringBuilder sb = new StringBuilder();
			if (bytes != null)
			{
				for (int i = 0; i < bytes.Length; i++)
				{
					sb.Append(bytes[i].ToString("X2"));
				}
			}
			return sb.ToString() + "\n";
		}

		// byte[] 转 string
		public static string Byte2HexString4RBF(byte[] bytes)
		{
			StringBuilder sb = new StringBuilder();
			if (bytes != null)
			{
				for (int i = 0; i < bytes.Length; i++)
				{
					if (i == 0)
					{
						sb.Append(i.ToString("X8").ToLower().PadLeft(8, '0') + "h: ");
					}
					else if (i > 0 && i % 16 == 0)
					{
						sb.Append("\n" + i.ToString("X8").ToLower().PadLeft(8, '0') + "h: ");
					}
					sb.Append(bytes[i].ToString("X2") + " ");
				}
			}
			return sb.ToString() + "\n";
		}

		// byte[] 转 string
		public static string Byte2HexString(byte[] bytes, int length)
		{
			string str = String.Empty;
			if (bytes != null)
			{
				for (int i = 0; i < length; i++)
				{
					str += bytes[i].ToString("X2");
				}
			}
			return str + "\n";
		}

		// string 转 byte[]
		public static byte[] String2Bytes(string str)
		{
			return System.Text.Encoding.Default.GetBytes(str);
		}

        public static byte[] String2BytesEx(string str)
        {
            int bytelen = str.Length / 2;
            byte[] result = new byte[bytelen];
            str = str.ToLower();
            for (int i = 0; i < str.Length; i += 2)
            {
                int x = str[i];
                if ((48 <= x) && (x <= 57))
                {
                    x -= 48;
                }
                else if ((97 <= x) && (x <= 102))
                {
                    x -= 87;
                }
                x = x & 0xf;
                int y = str[i + 1];
                if ((48 <= y) && (y <= 57))
                {
                    y -= 48;
                }
                else if ((97 <= y) && (y <= 102))
                {
                    y -= 87;
                }
                y = y & 0xf;

                result[i / 2] = (byte)((x << 4) | y);
            }

            return result;
        }

		// 字符串转 16 进制字节数组 
		public static byte[] StringToHexByte(string hexString)
		{
			hexString = hexString.Replace(" ", "");
			if ((hexString.Length % 2) != 0)
				hexString += " ";
			byte[] returnBytes = new byte[hexString.Length / 2];
			for (int i = 0; i < returnBytes.Length; i++)
				returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);

			return returnBytes;
		}

		// 创建 24 位位图
		public static Bitmap build24BitMap(int width, int height, byte[] view_data)
		{
			int headerLength = 54;
			int bfSize_v = width * height * 3 + headerLength;

			byte[] data = new byte[headerLength + view_data.Length];

			byte[] bfType = System.Text.Encoding.Default.GetBytes("BM");	// 图片类型
			byte[] bfSize = int2Byte4(bfSize_v);	// 位图文件大小 - 字节为单位
			byte[] bfReserced = int2Byte4(0);		// 保留 - 设置为0
			byte[] bfOffBits = int2Byte4(54);		// 从文件头开始到实际图像数据之间的字节偏移量

			byte[] biSize = int2Byte4(40);			// BMP文件头所需字节数
			byte[] biWidth = int2Byte4(width);		// 图像宽度 - 像素为单位
			byte[] biHeight = int2Byte4(height);	// 图像高度 - 像素为单位
			byte[] biPlanes = int2Byte2(1);			// 颜色平面数, 总为1
			byte[] biBitCount = int2Byte2(24);		// 像素位宽, 其值为1、4、8、16、24、32
			byte[] biCopression = int2Byte4(0);		// 数据压缩类型：0-不压缩
			byte[] biSizeImage = int2Byte4(0);		// 图像大小, 字节为单位, BI_RGB格式下可为0
			byte[] biXpelsPerMeter = int2Byte4(0);	// 水平分辨率 像素/米
			byte[] biYpelsPerMeter = int2Byte4(0);	// 垂直分辨率 像素/米
			byte[] biClrUsed = int2Byte4(0);		// 位图实际使用的彩色表中的颜色索引数, 若为0说明使用所有的调色板项
			byte[] biClrImportant = int2Byte4(0);	// 对图像显示有重要影响的颜色索引数目, 若为0说明都重要

			int index = 0;

			// 组装 bmp 文件头
			addByte(ref data, bfType, ref index);
			addByte(ref data, bfSize, ref index);
			addByte(ref data, bfReserced, ref index);
			addByte(ref data, bfOffBits, ref index);

			// 组装 bmp 信息头
			addByte(ref data, biSize, ref index);
			addByte(ref data, biWidth, ref index);
			addByte(ref data, biHeight, ref index);
			addByte(ref data, biPlanes, ref index);
			addByte(ref data, biBitCount, ref index);
			addByte(ref data, biCopression, ref index);
			addByte(ref data, biSizeImage, ref index);
			addByte(ref data, biXpelsPerMeter, ref index);
			addByte(ref data, biYpelsPerMeter, ref index);
			addByte(ref data, biClrUsed, ref index);
			addByte(ref data, biClrImportant, ref index);

			// 组装显示数据
			addByte(ref data, view_data, ref index);

			// 利用内存流生成图片
			MemoryStream ms = new MemoryStream(data);
			Bitmap bmp = (Bitmap)Bitmap.FromStream(ms);

			// 镜像操作
			bmp.RotateFlip(RotateFlipType.Rotate180FlipX);

			return bmp;
		}

		// byte[]拼接
		public static void addByte(ref byte[] oriBytes, byte[] newBytes, ref int index)
		{
			Array.Copy(newBytes, 0, oriBytes, index, newBytes.Length);
			index += newBytes.Length;
		}

		// byte[]拼接
		public static void addByte(ref byte[] oriBytes, byte newByte, ref int index)
		{
			byte[] b = new byte[1];
			b[0] = newByte;
			Array.Copy(b, 0, oriBytes, index, b.Length);
			index += b.Length;
		}

		// int 转 byte[2]
		public static byte[] int2Byte2(int i)
		{
			byte[] b = new byte[2];
			b[0] = (byte)(0xff & i);
			b[1] = (byte)((0xff00 & i) >> 8);

			return b;
		}

        // int 转 byte[2] - 高字节在前低字节在后
        public static byte[] int2Byte2LE(int i) {
            return reverseArray(int2Byte2(i));
        }

		// int 转 byte[4] - 低字节在前高字节在后
		public static byte[] int2Byte4(int i)
		{
			byte[] b = new byte[4];
			b[0] = (byte)(0xff & i);
			b[1] = (byte)((0xff00 & i) >> 8);
			b[2] = (byte)((0xff0000 & i) >> 16);
			b[3] = (byte)((0xff000000 & i) >> 24);

			return b;
		}

        // uint 转 byte[4] - 低字节在前高字节在后
        public static byte[] uint2Byte4(uint i) {
            byte[] b = new byte[4];
            b[0] = (byte)(0xff & i);
            b[1] = (byte)((0xff00 & i) >> 8);
            b[2] = (byte)((0xff0000 & i) >> 16);
            b[3] = (byte)((0xff000000 & i) >> 24);

            return b;
        }

		// int 转 byte[4] - 低字节在前高字节在后
		public static byte[] int2Byte6(int i)
		{
			byte[] b = new byte[6];
			b[0] = (byte)(0xff & i);
			b[1] = (byte)((0xff00 & i) >> 8);
			b[2] = (byte)((0xff0000 & i) >> 16);
			b[3] = (byte)((0xff000000 & i) >> 24);
			b[4] = (byte)((0xff00000000 & i) >> 32);
			b[5] = (byte)((0xff0000000000 & i) >> 40);

			return b;
		}

        public static byte[] reverseArray(byte[] arr) {
            var list = arr.ToList();
            list.Reverse();
            var ret = list.ToArray();
            return ret;
        }

		// 计算 CRC32
		public static int getCRC32(byte[] bytes)
		{
			int iCount = bytes.Length;
			UInt32 crc = 0xFFFFFFFF;
			for (int i = 0; i < iCount; i++)
			{
				crc = ((crc >> 8) & 0x00FFFFFF) ^ crcTable[(crc ^ bytes[i]) & 0xFF];
			}
			UInt32 temp = crc ^ 0xFFFFFFFF;
			int t = (int)temp;
			return (t);
		}

		// 位转换 bit swap
		public static byte bitSwap(byte value)
		{
			return bitSwapTable[value];
		}

        // 位转换 bit swap
        public static byte bitSwap2(byte data) {
            data = (byte)((data << 4) | (data >> 4));
            data = (byte)(((data << 2) & 0xcc) | ((data >> 2) & 0x33));
            data = (byte)(((data << 1) & 0xaa) | ((data >> 1) & 0x55));
            return data;
        }

		// 比较字节数组
		public static int MemoryCompare(byte[] b1, byte[] b2)
		{
			if (b1 == null || b2 == null)
			{
				return 1;
			}

			int result = 0;
			if (b1.Length != b2.Length)
			{
				result = b1.Length - b2.Length;
			}
			else
			{
				for (int i = 0; i < b1.Length; i++)
				{
					if (b1[i] != b2[i])
					{
						result = (int)(b1[i] - b2[i]);
						break;
					}
				}
			}

			return result;
		}

        public static void CopyByte(ref byte[] target, byte[] source, int len, int offsetpos = 0, int startpos = 0)
        {
            for (int i = 0; i < len; i++)
            {
                target[offsetpos + i] = source[i + startpos];
            }
        }

        public static byte[] IP2Byte(string ip)
        {
            byte[] ipbyte = new byte[4];
            string[] IPPart = ip.Split(new char[] { '.' });
            for (int i = 0; i < 4; i++)
            {
                ipbyte[i] = byte.Parse(IPPart[i]);
            }

            return ipbyte;
        }

        public static UInt16 BytesTo16(byte x, byte y)
        {
            UInt16 result = x;
            result = (UInt16)(result << 8);
            result = (UInt16)(result | y);
            return result;
        }

        public static float Mult10Pow(int val, int prefix) {
            return (float)(val * Math.Pow(10, prefix));
        }
	}
}
